package mgodb

import (
	"jgt-wallet/src/model"
	"jgt-wallet/src/schema"
	"jgt-wallet/src/service/mongo"

	"github.com/facebookgo/inject"
	"github.com/globalsign/mgo"
	"github.com/globalsign/mgo/bson"
	"github.com/pkg/errors"
)

// cOrder 交易订单
const cOrder = "wallet_order"

// Order 订单管理
type Order struct {
	DB *mongo.DB
}

// Init 初始化
func (a *Order) Init(g *inject.Graph, db *mongo.DB) {
	a.DB = db

	// 初始化mongo索引
	a.DB.C(cOrder, func(c *mgo.Collection) error {
		c.EnsureIndex(mgo.Index{
			Key:    []string{"record_id"},
			Unique: true,
		})
		c.EnsureIndexKey("order_id")
		c.EnsureIndexKey("user_id")
		c.EnsureIndexKey("pay_type")
		c.EnsureIndexKey("client")
		c.EnsureIndexKey("created")
		return nil
	})

	var val model.IOrder = a
	g.Provide(&inject.Object{Value: val, Name: "IOrder"})
}

// QueryOrder 查询订单
func (a *Order) QueryOrder(param *schema.OrderQueryParam) (int64, []*schema.Order, error) {
	var (
		query = bson.M{}
		err   error
		total int64 = 0
		items []*schema.Order
	)

	if len(param.Sort) == 0 {
		param.Sort = []string{
			"-_id",
			"pay_type",
		}
	}

	if v := param.OrderID; v != "" {
		query["order_id"] = v
	}

	if param.Page {
		err = a.DB.C(cOrder, func(c *mgo.Collection) error {

			n, err := c.Find(query).Count()
			if err != nil {
				return err
			}
			total = int64(n)
			if total == 0 {
				return nil
			}

			return c.Find(query).Sort(param.Sort...).Skip(param.PageFrom).Limit(param.PageSize).All(&items)

		})
		if err != nil {
			return 0, nil, errors.Wrapf(err, "查询分页数据发生错误")
		}
	} else {
		if param.Total {
			err = a.DB.C(cOrder, func(c *mgo.Collection) error {
				n, err := c.Find(query).Count()

				total = int64(n)

				return err

			})
			if err != nil {
				return 0, nil, errors.Wrapf(err, "查询记录数发生错误")
			}
		} else {
			err = a.DB.C(cOrder, func(c *mgo.Collection) error {

				return c.Find(query).Sort(param.Sort...).All(&items)

			})
			if err != nil {
				return 0, nil, errors.Wrapf(err, "查询列表数据发生错误")
			}
		}

	}
	return total, items, nil
}

// GetOrder 获取订单
func (a *Order) GetOrder(pk map[string]interface{}) (*schema.Order, error) {
	var item schema.Order
	err := a.DB.C(cOrder, func(c *mgo.Collection) error {
		return c.Find(pk).One(&item)
	})
	if err != nil {
		if err == mgo.ErrNotFound {
			return nil, nil
		}
		return nil, errors.Wrapf(err, "根据编号和类型查询数据发生错误")
	}
	return &item, nil
}

// CreateOrder 新建订单
func (a *Order) CreateOrder(item *schema.Order) error {
	err := a.DB.C(cOrder, func(c *mgo.Collection) error {
		id, err := a.DB.IncrID(cOrder)
		if err != nil {
			return err
		}
		item.ID = id
		return c.Insert(item)
	})
	if err != nil {
		return errors.Wrapf(err, "创建数据发生错误")
	}

	return nil
}

// UpdataOrder 修改订单
func (a *Order) UpdateOrder(pk, info map[string]interface{}) error {
	err := a.DB.C(cOrder, func(c *mgo.Collection) error {
		return c.Update(pk, bson.M{"$set": info})
	})
	if err != nil {
		return errors.Wrapf(err, "更新数据发生错误")
	}
	return nil
}
